import math

from _global import dist, distSq

def checkBoundCollision(d1, d2):
	d1type = type(d1.coll.bound)
	d2type = type(d2.coll.bound)
	
	hit = False	#Flag to store whether the inner volumes hit
	
	if d1type == BoundSphere:
		if d2type == BoundSphere:
			#See if distance between sphere origins is less than combined radii
			actualDistSq = distSq(d1.origin + d1.moveTo, d2.origin)
			minDist = d1.coll.bound.radius + d2.coll.bound.radius
			if actualDistSq <= minDist ** 2:
				hit = True
				#See if reaction is required
				if d1.phys and not d2 in d1.struck: #React and add to force accumulators
					#Find the overlap, a hypotenuse
					overlap = minDist - math.sqrt(actualDistSq)
					#Find the plane tangent to the hit
					#Add forces to accumulators for d1 and d2
					d2.phys.struck.append(d1) #Let d2 know to ignore d1 as an option to check physics
					pass
			
class AABB(object):
	"""Axis-aligned bounding box, does not inherit BoundVolume"""
	def __init__(self, drawable):
		self.parent = drawable
		self.offset = None
		self.size = None
	def scaleV(self, v):
		self.offset.multiplyScalarComponents(v)
		self.size.multiplyScalarComponents(v)
	@property
	def top(self):
		return self.parent.origin.y + self.offset.y
	@property
	def bottom(self):
		return self.top - self.size.y
	@property
	def left(self):
		return self.parent.origin.x - self.offset.x
	@property
	def right(self):
		return self.left + self.size.x
	@property
	def back(self):
		return self.parent.origin.z - self.offset.z
	@property
	def front(self):
		return self.back + self.size.z

class BoundVolume(object):
	def __init__(self, drawable):
		self.parent = drawable
	
	def updateAABB(self):
		"""Return an Axis-aligned bounding box that surrounds the volume as close as possible"""
		pass
	
	def scale(self, v):
		"""Inherited to scale bounding volume appropriately"""
		pass

class BoundSphere(BoundVolume):
	"""Bounding Sphere"""
	def __init__(self, drawable):
		super(BoundSphere, self).__init__(drawable)
		
		self.radius = 0				#Sphere radius
		self.offset = Vector3()	#Offset from origin, default (0,0,0)
	
	def updateAABB(self):
		super(BoundSphere, self).getAABB()
		
		diameter = self.radius * 2
		box = self.parent.coll.box
		box.size = Vector3(diameter, diameter, diameter)
		box.offset = self.offset
	
	def scale(self, s):
		"""For spheres, the scale value is a scalar"""
		self.radius *= s
		self.updateAABB()
	
class BoundOBB(BoundVolume):
	"""Oriented Bounding Box"""
	def __init__(self, drawable):
		super(BoundOBB, self).__init__(drawable)
		
		self.offset = None			#"axis aligned" box offset, Vector3
		self.size = None			#"axis aligned" box size, Vector3
		self.rotation = Vector3()	#box rotation for each axis in degrees, default (0,0,0)
	
	def getAABB(self):
		pass
	
	def scale(self, v):
		pass